package stv5.handlers;

import java.util.HashMap;
import java.util.Map.Entry;

import stv5.Request;
import stv5.Response;
import stv5.Series;
import stv5.SeriesList;
import stv5.Settings;
import stv5.abstracted.RequestHandler;
import us.danlib.templating.Template;
import us.danlib.templating.Templator;

public class SettingsHandler extends RequestHandler {
	private Settings mySettings;
	private Templator settingsList, settingsRebuild, settingsGeneric;

	public SettingsHandler(Settings mySettings) {
		this.mySettings = mySettings;
		settingsList = new Templator("template/settings.list.tpl");
		settingsRebuild = new Templator("template/settings.rebuild.tpl");
		settingsGeneric = new Templator("template/settings.generic.tpl");
	}

	@Override
	protected boolean handle(Request request, Response response) {
		response.setContentType("text/html");
		switch (request.getType()) {
			case SAVE:
				save(request, response );
			break;		
			case VIEW:
				view(request, response );
			break;
			default:
				// unhandled type
				return false;
		}
		return true;
	}

	private void save(Request request, Response response) {
		if (!request.hasVar("page")) 
			return;
		
		Template t = settingsGeneric.createTemplate("HOME_LINK", "../../");				
		StringBuffer buff = new StringBuffer();
		
		if ("rebuild".equals( request.getVar("page") )) {
			// clean up the request data
			int guidEnd;
			String guid, name;
			// TODO: It wouldn't hurt to use SeriesList here, too
			HashMap<String, String> data = new HashMap<String, String>();
			for (Entry<String, String> e : request.getVars()) {
				// we're only going to look at the "named" ones
				guidEnd = e.getKey().indexOf("_name");
				if (guidEnd > -1) { 
					guid = e.getKey().substring(0, guidEnd);
					name = e.getValue();
					
					// if this series isn't actually on, ignore it
					if (!(request.hasVar(guid) && "on".equals(request.getVar(guid)))) 
						continue;
					
					// store the data
					data.put(name, guid);
				}
			}
			mySettings.rebuildDb(data, "on".equals(request.getVar("_delete_old")));
						
			mySettings.reload();
			
			buff.append("Database rebuilt!");
		}
		else if ("restart".equals( request.getVar("page") )) {
			mySettings.reload();
			buff.append("SeriesTracker v5 Restarted!");			
		}
		else mySettings.handleRequest(buff, request);

		t.addGlobalVar("BODY", buff.toString());
		
		response.setBody( t.render() );
	}


	private void view(Request request, Response response) {		
		if (!request.hasVar("page")) {
			// TODO: In the future, I should enforce order by not
			// using HashMap... oh well
			HashMap<String, String> links = new HashMap<String, String>();
			links.put("Rebuild Database", "?page=rebuild");
			links.put("Restart STv5", "../save/?page=restart");
			mySettings.appendSettingsList(links);
			
			Template t = settingsList.createTemplate("HOME_LINK", "../../");
			for (Entry<String, String> e : links.entrySet()) 
				t.addClass("link", "LINK_TEXT", e.getKey(), "LINK_URL", e.getValue());
						
			response.setBody( t.render() );
		}
		else if ("rebuild".equals(request.getVar("page"))) {
			SeriesList folders = request.hasVar("start") ? 
					mySettings.spiderFolders(request.getVar("start"))
					: mySettings.spiderFolders();
					
			Template t = settingsRebuild.createTemplate(
					"HOME_LINK", "../../",
					"NUM_FOLDERS", ""+folders.size(),
					"FORM_ACTION", "../save/?page=rebuild"
			);
			
			// display folders found, sorted
			String folder;
			for(Series s : folders.sorted()) {
				folder = s.getName();
				t.beginClass("found_folder");					
				t.addClassVar("SERIES_NAME", folder); 
				t.addClassVar("SERIES_GUID", s.getGuid());
				if (mySettings.hasSeries( folder ))
					t.addClassVar("SERIES_EXISTS", "1");
				t.endClass();
			}
			
			boolean contains, missing = false;
			for (Series s : mySettings.getSeries()) {
				// loop so we can ignore case
				contains = false;
				for (Series other : folders)
					if (s.getName().equalsIgnoreCase(other.getName())) {
						contains = true;
						break;
					}
				if (!contains) {					
					t.addClass("missing", "SERIES_NAME", s.getName());
					missing = true;
				}
			}
			if (!missing)
				t.addGlobalVar("NONE_MISSING", "1");
						
			response.setBody( t.render() );
					
			/*
			buff.append("Found " + folders.size() + " folders.<br>");
			buff.append("Check the folders you wish to track as series. ");
			buff.append("If the series is already tracked, it will be highlighted, and ");
			buff.append("its current episode will not be affected.");
			
			buff.append("<form action=\"../save/?page=rebuild\" method=\"POST\">");
			buff.append("<p><ul class=\"rebuild-list\">");
			
			// display sorted
			String guid, folder;
			for(Series s : folders.sorted()) {
				guid = s.getGuid();
				folder = s.getName();
				buff.append("<li" + ((mySettings.hasSeries(folder)) ? " class=\"exists\">" : ">") +
						"<input type=\"checkbox\" name=\""+guid+"\" id=\""+guid+"\" CHECKED>"+
						"<input type=\"hidden\" name=\""+guid+"_name\" value=\""+folder+"\">"+
						"<label for=\""+guid+"\">"+folder+"</label></li>\n");
			}
			buff.append("</ul></p>");
			buff.append("<p><input type=\"checkbox\" name=\"_delete_old\" " +
					"id=\"_delete_old\" CHECKED>\n" +
					"<label for=\"_delete_old\">Delete non-checked/not-found series</label></p>\n");
			buff.append("<div id=\"missing-series\"><h4>Series that were not found:</h4>\n");
			boolean missing = false, contains;
			for (Series s : mySettings.getSeries()) {
				// loop so we can ignore case
				contains = false;
				for (Series other : folders)
					if (s.getName().equalsIgnoreCase(other.getName())) {
						contains = true;
						break;
					}
				if (!contains) {					
					buff.append("<span>"+s.getName()+"</span>");
					missing = true;
				}
			}
			if (!missing)
				buff.append("None!");
			buff.append("</div>\n");
			buff.append("<div style=\"clear:left\"></div>");
			buff.append("<p><input type=\"submit\" value=\"Update DB!\"></p>\n</form>");
			*/
		}		
		
		/*
		buff.append(getNavigation());
		buff.append(getStandardFooters());
		return buff.toString();
		*/
	}
}
